<?php

namespace App\Jobs;

use App\Models\ApiGateway;
use App\Models\ApiKey;
use App\Models\ApiKeyRequestLog;
use App\Models\Charge;
use App\Services\Utils\Utils;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class Consumption implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $apikey;
    protected $routeName;
    protected $group;
    protected $apiName;
    protected $host;
    protected $url;
    protected $faceData;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($apikey, $route_name, $group, $api_name, $host, $url, $face_data)
    {
        $this->apikey = $apikey;
        $this->routeName = $route_name;
        $this->group = $group;
        $this->apiName = $api_name;
        $this->host = $host;
        $this->url = $url;
        $this->faceData = $face_data;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $apikeyRecord = ApiKey::where('key', $this->apikey)->first();
        if (!isset($apikeyRecord)){
            return;
        }
        $customer = $apikeyRecord->customer;
        $_group = $this->group;
        $_name = $this->apiName;
        $price = Utils::getApiPriceList()->$_group->$_name->price;
        $this->insertApiLog($apikeyRecord->id,
                            $this->routeName,
                            $this->host,
                            $this->url,
                            $this->faceData,
                            $customer->id,
                            $price,
                            $apikeyRecord->type);
    }

    private function insertApiLog($app_id, $api, $host, $url, $face_data, $customer_id, $price, $api_type)
    {
        $data = json_decode($face_data);
        if($data){
            if (!isset($data->code)){   //请求超时失败
                return;
            }else if ($data->code == 200) {   //请求成功
                $success = 1;
                $error = null;
            }else{  //请求失败
                $success = 0;
                $error = $data->message;
            }
        
            //写入调用日志
            $log_id = ApiKeyRequestLog::insertGetId([
                'app_id' => $app_id,
                'api' => $api,
                'host' => $host,
                'url' => $url,
                'params' => '',
                'success' => $success,
                'error' => $error,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now()
            ]);
    
            if ($data->code == 200) {  //调用成功
                if (empty($api_type) || $api_type == 0) {  //测试类型
                    Cache::put($this->apikey, $this->apikey, env('API_KEY_THRESHOLD')); //将该apikey写入缓存
                }
                elseif ($api_type == 1){ //按次计费类型
                        $this->insertCharges($customer_id, $price, $log_id);    //进行扣费
                }
                elseif ($api_type == 2 || $api_type == 3) {   //按时间节段计费和永久授权类型
                        $endpoint = ApiGateway::where([
                                                'apikey_id' => $app_id,
                                                'group'     => $this->group,
                                                'endpoint' => $this->apiName,
                                            ])->first();
                        if (!isset($endpoint)) {    //该apikey未关联当前请求的api
                            $this->insertCharges($customer_id, $price, $log_id);    //进行扣费
                        }
                }else{ // 其他
                    //todo 其他计费类型可以在这里实现
                }
            }
        }
    }

    private function insertCharges($customer_id, $price, $log_id)
    {
        $change_before = Charge::where('customer_id', $customer_id)->latest()->value('change_after');
        $change_after = $change_before - $price;
        $params = array(
            'log_id' => $log_id
        );

        $charge = new Charge;
        $charge->customer_id = $customer_id;
        $charge->change_before = $change_before;
        $charge->change_after = $change_after;
        $charge->change_type = 'apikey_consume';
        $charge->change_params = json_encode($params);
        $charge->remark = 'apikey请求扣费'.($price/100.0).'元';
        $charge->created_at = Carbon::now();
        $charge->save();
    }
}
